#!/usr/bin/python
# -*- coding: utf-8 -*-
#   gLabs NMR, an application to open and reprocess nmr data provided by 
#       various, commercial avaible applications.
#   Copyright (C) 2011 Basilius Sauter
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#  
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

import sys
import os
import struct
import glob

import scipy
import numpy
try:
    import pygtk
    pygtk.require("2.0")
except:
    print "PyGTK not found."
    sys.exit(1)
import gtk
import gtk.glade

# gLabs NMR libs
import lib

class Application(object):
    """Dies ist die gNMR-Applikation"""
    version = "0.1"
    
    # Aha...
    pathprefix = ""
    
    glade_files = [
        "gui/gui.glade",
        "gui/newworkspace.glade",
        "gui/dialog_calibrate.glade",
        "gui/dialog_about.glade",
        "gui/dialog_spectrumprintsettings.glade"
    ]
    
    glade_main = "gui/gui.glade"
    glade_dialog_createworkspace = "gui/newworkspace.glade"
    glade_dialog_calibrate = "gui/dialog_calibrate.glade"
    glade_dialog_about = "gui/dialog_about.glade"
    glade_dialog_spectrumprintsettings = "gui/dialog_spectrumprintsettings.glade"
    
    mainWindow = None
    builder = None
    
    # Objects
    oWorkspace = None
    o_dialogs = None
    
    # Tmp Data
    createWorkspaceData = {}
    
    def __init__(self, sysarg = ""):
        # Setze das Pfad-Prefix
        self.pathprefix = os.path.join(os.curdir, os.path.dirname(sys.argv[0]))
        
        # Vorbereiten der App
        self.builder = gtk.Builder()
        
        path = os.path.join(self.pathprefix, "gui", "*.glade")
        gladefiles = glob.glob(path)
        
        for f in gladefiles:
            self.builder.add_from_file(f)
        #print glob.glob(path)
        #print "Lookup-Path: %s (%s)" % (path, self.pathprefix)
        #self.builder.add_from_file(os.path.join(self.pathprefix, self.glade_main))
        #self.builder.add_from_file(os.path.join(self.pathprefix, self.glade_dialog_createworkspace))
        #self.builder.add_from_file(os.path.join(self.pathprefix, self.glade_dialog_calibrate))
        #self.builder.add_from_file(os.path.join(self.pathprefix, self.glade_dialog_about))
        #self.builder.add_from_file(os.path.join(self.pathprei
        
        # Vorbereiten wichtiger Objekte
        self.oWorkspace = lib.Workspace(self)
        
        # Signale verbinden
        dic = {
            "on_mainWindow_destroy" : self.quit,
            "on_menu_quit_activate" : self.quit,
            
            ### Abaut
            "on_gtkAbout_activate" : self.on_gtkAbout_activate,
            "on_gtkAbout_close" : self.on_gtkAbout_close,
            
            ### Menu
            "on_menu_openworkspace_activate" : self.on_menu_openworkspace_activate,
            "on_menu_spectrum_printSpectrum_activate" : self.oWorkspace.on_menu_spectrum_printSpectrum_activate,
            "on_menu_spectrum_printPageSettings_activate" : self.oWorkspace.on_menu_spectrum_printPageSettings_activate,
            "on_menu_spectrum_printSpectrumSettings_activate" : self.oWorkspace.on_menu_spectrum_printSpectrumSettings_activate,
            
            ### Workspace-Dialog
            # 
            "on_menu_newworkspace_activate" : self.show_createworkspace_assistant,
            "on_createWorkspaceAssistant_cancel" : self.on_createWorkspaceAssistant_cancel,
            "on_createWorkspaceAssistant_apply" : self.on_createWorkspaceAssistant_apply,
            # Step 1
            "on_cWsA_openSaveDialog_activate" : self.on_cWsA_openSaveDialog_activate,
            "on_cWsA_filepath_changed" : self.on_cWsA_filepath_changed,
            # Step 2
            "on_cWsA_openNMRPAthDialog_clicked" : self.on_cWsA_openNMRPAthDialog_clicked,
            "on_cWsA_nmrpath_changed" : self.on_cWsA_nmrpath_changed,
            
            ### Tree View
            "on_nmrOverviewTree_row_activated" : self.oWorkspace.onRowActivated,
            
            ### Configure Event
            "configure_event" : self.oWorkspace.configureDrawingArea,
            "nmrDraw_expose" : self.oWorkspace.exposeDrawingArea,
            "on_nmrArea_move" : self.oWorkspace.onNmrAreaMove,
            "on_nmrArea_leave" : self.oWorkspace.on_nmrArea_leave,
            
            ### Allgemeine SIgnale
            "on_activatePeakPicking_toggled" : self.oWorkspace.on_activatePeakPicking_toggled,
            "on_activateIntegrate_toggled" : self.oWorkspace.on_activateIntegrate_toggled,
            "on_nmrArea_buttonPressed" : self.oWorkspace.on_nmrArea_buttonPressed,
            "on_nmrArea_buttonReleased" : self.oWorkspace.on_nmrArea_buttonReleased,
            "onActivateSpectrumSave" : self.oWorkspace.onActivateSpectrumSave,
            "onActivateWidenTwice" : self.oWorkspace.onActivateWidenTwice,
            "onActivateShortenTwice" : self.oWorkspace.onActivateShortenTwice,
            
            ### Signale für die Plot-Area
            "on_contextDeleteIntegral_activate" : self.oWorkspace.on_contextDeleteIntegral_activate,
            "on_contextDeletePeak_activate" : self.oWorkspace.on_contextDeletePeak_activate,
            "on_contextCalibrateIntegral_activate" : self.oWorkspace.on_contextCalibrateIntegral_activate,
            
            "on_calibrateDialog_close" : self.oWorkspace.on_calibrateDialog_close,
            "on_calibrateDialog_abort" : self.oWorkspace.on_calibrateDialog_close,
            "on_calibrateDialog_form_calibrateInput_changed" : self.oWorkspace.on_calibrateDialog_form_calibrateInput_changed,
            "on_calibrateDialog_commit" : self.oWorkspace.on_calibrateDialog_commit,
            
            ### PrintSpectrumSettings-Dialog
            "on_spectrumprintsettingsDialog_form_input_changed" : self.oWorkspace.on_spectrumprintsettingsDialog_form_input_changed,
            "on_spectrumprintsettingsDialog_close" : self.oWorkspace.on_spectrumprintsettingsDialog_close,
            "on_spectrumprintsettingsDialog_abort" : self.oWorkspace.on_spectrumprintsettingsDialog_close,
            "on_spectrumprintsettingsDialog_commit" : self.oWorkspace.on_spectrumprintsettingsDialog_commit,
            
            # Sonstiges
            "on_debug_destory" : self.on_debug_destory,
            "do_not_delete" : self.do_not_delete,
        }
        self.builder.connect_signals(dic)
        
        self.builder.get_object('nmrArea').connect('expose-event', self.oWorkspace.exposeDrawingArea)
        
        # Noch ein paar Ergänzungen zum GUI
        self.createWorkspaceAssistant = self.builder.get_object('createWorkspaceAssistant')
        self.createWorkspaceAssistant.set_page_title(self.createWorkspaceAssistant.get_nth_page(0), "Datei speichern")
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(0), False)
        self.createWorkspaceAssistant.set_page_title(self.createWorkspaceAssistant.get_nth_page(1), "NMR-Pfad wählen")
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(1), False)
        
        # Andere...
        self.o_dialogs = {
            'about' : self.builder.get_object('gNMR_about'),
            'calibrate' : self.builder.get_object('calibrateDialog'),
            'spectrumprintsettings' : self.builder.get_object('spectrumprintsettingsDialog'),
        }
        self.calibrateDialog = self.builder.get_object('calibrateDialog')
        self.aboutDialog = self.builder.get_object('gNMR_about')
        
        # Filter...
        self.defaultFilter = gtk.FileFilter() 
        self.defaultFilter.add_pattern("*.gnmr")
        
        # Vorbereiten des Hauptfensters
        self.mainWindow = self.builder.get_object('mainWindow')
        self.mainWindow.set_title('gLabs NMR')
        #self.mainWindow.maximize()
         
    def run(self):
        """ Run the Application """
        # Fenster anzeigen
        self.mainWindow.show()
        
        # Hauptroutine
        try:
            gtk.main()
        except KeyboardInterrupt:
            self.quit
        
    def quit(self, element):
        """ Quit the application """

        # Schliesse workspace
        self.oWorkspace.close()
        
        # Schliesse Hauptroutine
        gtk.main_quit()
        
    def addFilenameToTitle(self, filename = None):
        """ Add the current filename to the window title in brackets. """
        if filename == None:
            self.mainWindow.set_title("gLabs NMR")
        else:
            self.mainWindow.set_title("gLabs NMR [" + filename + "]")
        
###
# Arbeitsflächen-Erstellungs-Assi.
###
    def show_createworkspace_assistant(self, element):
        """ Show the assistant for creating a workspace """
        self.createWorkspaceAssistant.show()
        
    def on_createWorkspaceAssistant_cancel(self, element):
        """ Abort the assistant without saving """
        self.clearCreateworkspace_assistant()
        self.createWorkspaceAssistant.hide()
        
    def clearCreateworkspace_assistant(self):
        """ Clear all temp data from the assistant and clean the formular """
        self.createWorkspaceData = {}
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(0), False)
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(1), False)
        
    def on_createWorkspaceAssistant_apply(self, e):
        """ Apply the changes from the assistant:
        Create a File, clear the assistant and hide himself.

        """
        self.oWorkspace.create(self.createWorkspaceData["filepath"], self.createWorkspaceData["nmrpath"])
        self.clearCreateworkspace_assistant()
        self.createWorkspaceAssistant.hide()
        
    def on_cWsA_openSaveDialog_activate(self, e):
        """ Open a save-dialog to select a pathname for the file """
        dlg = gtk.FileChooserDialog(
            title = 'Datei speichern',
            parent = self.createWorkspaceAssistant,
            action = gtk.FILE_CHOOSER_ACTION_SAVE,
            buttons = (
                gtk.STOCK_CANCEL,
                gtk.RESPONSE_REJECT,
                gtk.STOCK_OK,
                gtk.RESPONSE_OK
            )
        )
    
        dlg.set_do_overwrite_confirmation(True)
        dlg.set_filter(self.defaultFilter)
        result = dlg.run()

        if result == gtk.RESPONSE_OK:
            self.createWorkspaceData["filepath"] = dlg.get_filename()
            self.builder.get_object('cWsA_filepath').set_text(self.createWorkspaceData["filepath"])
        else:
            print "Abort."
            self.path = None
            dlg.hide()

        dlg.destroy()
        
    def on_cWsA_filepath_changed(self, e):
        """ React on a changed filepath """
        self.createWorkspaceData["filepath"] = e.get_text()
        self.createWorkspaceData["state"] = 1;
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(0), True)
        self.builder.get_object("filepath_label").set_text(self.createWorkspaceData["filepath"])
        
    def on_cWsA_openNMRPAthDialog_clicked(self, e):
        """ Open a Folder-Choose-Dialog to let the user pick the userdir for nmr """
        dlg = gtk.FileChooserDialog(
            title = 'NMR-Pfad wählen',
            parent = self.createWorkspaceAssistant,
            action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
            buttons = (
                gtk.STOCK_CANCEL,
                gtk.RESPONSE_REJECT,
                gtk.STOCK_OK,
                gtk.RESPONSE_OK
            )
        )
    
        dlg.set_do_overwrite_confirmation(True)
        dlg.set_filter(self.defaultFilter)
        result = dlg.run()

        if result == gtk.RESPONSE_OK:
            self.createWorkspaceData["nmrpath"] = dlg.get_filename()
            self.builder.get_object('cWsA_nmrpath').set_text(self.createWorkspaceData["nmrpath"])
        else:
            self.path = None
            dlg.hide()

        dlg.destroy()
                
    def on_cWsA_nmrpath_changed(self, e):
        """ Save the nmrpath in a temporary variable and activate the next page of the assistant """
        self.createWorkspaceData["nmrpath"] = e.get_text()
        self.createWorkspaceData["state"] = 2;
        self.createWorkspaceAssistant.set_page_complete(self.createWorkspaceAssistant.get_nth_page(1), True)
        self.builder.get_object("nmrpath_label").set_text(self.createWorkspaceData["nmrpath"])
    
    def on_menu_openworkspace_activate(self, e):
        """ Open a File-Open-Dialog to load a file """
        dlg = gtk.FileChooserDialog(
            title = 'Datei laden',
            parent = self.createWorkspaceAssistant,
            action = gtk.FILE_CHOOSER_ACTION_OPEN,
            buttons = (
                gtk.STOCK_CANCEL,
                gtk.RESPONSE_REJECT,
                gtk.STOCK_OK,
                gtk.RESPONSE_OK
            )
        )
    
        dlg.set_do_overwrite_confirmation(True)
        dlg.set_filter(self.defaultFilter)
        result = dlg.run()

        if result == gtk.RESPONSE_OK:
            filename = dlg.get_filename()
            self.oWorkspace.open(filename)
        else:
            self.path = None
            
        dlg.destroy()
    
    def on_gtkAbout_activate(self, e):
        """ Show the about dialog """
        self.aboutDialog.run()
        self.aboutDialog.hide()
        
    def on_gtkAbout_close(self, e, b = None):
        """ Hide the about dialog """
        print "Close Dialog"
        self.aboutDialog.hide()
        
        return False
        
    def do_not_delete(self, a, b):
        return False
        
    def on_debug_destory(self, e):
        print "DESTROY..."
        return False
                
if __name__ == "__main__":
    app = Application()
    app.run()
